
#include "RtCnPkgSender.h"

#if !defined LEN_PKG_H  && !defined (_NEW_PROTO_TP)
#define LEN_PKG_H

class CLenPkgConn;
typedef CConnConnectorT<CLenPkgConn>	CLenPkgConnConnector;

typedef ServerListT<CLenPkgConn>		CLenPkgConnServerList;
typedef CConnAcceptorSinkT<CLenPkgConn>	CLenPkgConnAcceptorSink;
typedef CConnAcceptorT<CLenPkgConn>		CLenPkgConnAcceptor;

class /*RT_API_EXPORT*/ CLenPkgConn : public CPkgSender
{
public:
	virtual RtResult SendData(
		CRtMessageBlock& inData,
		BOOL inSendImmediately = TRUE,
		BOOL inDestroyData = FALSE,
		DataPriority inPriority = DP_MEDIUM, 
		BOOL inNeedAck = TRUE);

	virtual RtResult SetOption(
		DWORD aCommand, 
		LPVOID aArg);

	virtual RtResult GetOption(
		DWORD aCommand, 
		LPVOID aArg);

	virtual RtResult Disconnect(
		RtResult aReason);
public:
	// interface IRtAcceptorConnectorSink
	virtual void OnConnectIndication(
		RtResult aReason,
		IRtTransport *aTrpt,
		IRtAcceptorConnectorId *aRequestId);

	virtual void OnReceive(
		CRtMessageBlock &aData,
		IRtTransport *aTrptId,
		CRtTransportParameter *aPara = NULL);

	virtual void OnSend(
		IRtTransport *aTrptId,
		CRtTransportParameter *aPara = NULL);

	virtual void OnDisconnect(
		RtResult aReason,
		IRtTransport *aTrptId);

	virtual void OnTimer(CRtTimerWrapper* aId);

public:
	//Unconnected time stamp
	CRtTimeValue GetDisconnTimestamp();
	void TryOnDisconnIndicate();
protected:
	void Reset();
	RtResult SendData_i();
public:
	CLenPkgConn(CRtConnectionManager::CType inConnType);
	virtual ~CLenPkgConn();

	void NeedKeepAlive(BOOL bNeedKeepAlive);
	void SetConnConnector(CLenPkgConnConnector* pConnConnector);
	//Cancel connect call, stop the handshake if connection hasn't made
	void CancelHandShake();
	void ScheduleConnectTimer(const CRtTimeValue& aTimeout) {}
	
	//In order to keep one instance of Server List.
	void SetServerList(CLenPkgConnServerList* pSvrList);
	void SetConnAcceptor(CLenPkgConnAcceptor* pConnAcceptor);
protected:
	void Reset4Recv();
protected:
	CRtMessageBlock *m_pmbSendLocData;	//local Data block for Send
	CRtMessageBlock *m_pmbRecvLocData;	//local Data block for Recv
	CRtMessageBlock *m_pmbLastGet;		//Last get Data block for OnRecv

	DWORD m_dwPDULen;	//Data Length should be received
	DWORD m_dwDataLen;

	CRtConnectionManager::CType m_cType;
	CLenPkgConnConnector* m_pConnConnector;		//Client use

	CLenPkgConnServerList* m_pSvrList;							//Server use
	CRtAutoPtr<CLenPkgConnAcceptor> m_pConnAcceptor;

	CRtTimeValue m_disconn_timestamp;
	CRtMutexThreadRecursive		m_mutex;
};

#endif	//LEN_PKG_H
